iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 30
1
Modern Web

從LINE BOT到資料視覺化:賴田捕手系列 第 30

第 30 天:DataVis:Packaged

  • 分享至 

  • xImage
  •  

第 30 天:DataVis:Packaged

好笑的是,我甚至還有點懷念那個該死的茉莉絲。告訴你一件事吧,千萬別向任何人聊起你和草泥馬一起相處過的這三十天。如果你這麼做,就表示你開始在想念草泥馬了。

~節錄自《賴田捕手》第二十六章

  大家好,終於來到鐵人賽的最後一天了。回頭來看一看我們學過的東西:

  1. Python
      扎扎實實的從頭開始學了 Python 這個程式語言。

  2. LINE BOT SDK
      透過 LINE 官方提供的套件 line-bot-sdk-python 來實作出我們的第一個聊天機器人,並利用我們學會的 Python 程式碼讓聊天機器人變得幽默風趣又貼心。

  3. Heroku Postgres
      將 LINE 聊天機器人瀚 Heroku 提供的資料庫 Heroku Postgres 串接在一起,並開始學習與資料庫相關的 SQL 語言。如此一來我們就可以請 LINE 聊天機器人幫我們隨時隨地記錄下我們需要的資料。

  4. Flask
      學習 Python 提供用來賺寫網頁的套件 Flask,並實作出一個需要帳號密碼才能登入的網站。在這個網站中,我們可以自由的瀏覽 LINE 聊天機器人幫我們記錄下的每一筆資料,也可以透過使用者提交表單,來選擇需要調閱的特定資料。

  5. DataVis by C3
      拿我們學習 Python 的經驗快速學習又一種程式語言 JavaScript。JavaScript 可以說是當今瀏覽器的基本架構,撐起了瀏覽器的一片天。為了把我們在 Heroku Postgres 當中儲存的資料以圖表的形式呈現在網頁上,學習了以 D3 為基礎做出的資料視覺化套件 C3。C3 所提供的幾種圖表包括甜甜圈圖、曲線圖、史丹佛圖,我們都試著畫了一次。最後再用 HTML 5 的事件處理器,在使用者不需提交表單回伺服器的情況下,快速回饋所需結果給瀏覽器使用者。

  這就是我們的 30 天。

  有沒有發現這真是萬事起頭難。第 01 天我們什麼都做不了,還在辛辛苦苦的建置 Python 環境。但是只要心一橫、開了頭,我們手上的工具就漸漸的多了起來,不知不覺能夠做到的事情也以我們想像不到的速度增加了。

  那今天我們要做什麼呢?不急,先來看個網頁。

https://ithelp.ithome.com.tw/upload/images/20191008/20120178IlqKNPv8Eu.png
圖一、Trulia 做出的精美互動式圖表,出處在這裡

  在該網頁中,Trulia 提供了 4 張圖表,每一張圖表環環相扣,只要用滑鼠點擊或是將游標移過去,相對應的資料就會在其他圖表中更新或是顯現出來。

  我們能夠做出這種網頁嗎?我們會畫甜甜圈圖、曲線圖、史丹佛圖,剛好就跟 Trulia 所使用的其中 3 張圖表是一樣的類型,那我們也能夠做出這樣環環相扣的圖表嗎?雖然我無法保證能夠做到 100% 相像,但可以來試試能不能用我們學到的各種技巧,做出有 87% 像的網頁吧。

建構圖表相依性:基本面板

  我們先來挑戰個簡單的,從兩張圖表開始,在這兩張圖表之間建立相依性。

<div class="container">
    <div class="row">
        <h1>Two Connected Charts:</h1>
    </div>
    <div class="row">
        <div class="col">
            <div id="pieChart"></div>
        </div>
        <div class="col">
            <div id="barChart"></div>
        </div>

    </div>
</div>
// 畫出基本的柱狀圖
var barChart = c3.generate({
    bindto: '#spline-chart',
    data: {
      columns: [['data1', 30, 200, 100, 400, 150, 250],
                ['data2', 50, 20, 10, 40, 15, 25],
                ['data3', 130, 150, 200, 300, 200, 100]], 
      type:'bar', 
      groups:[['data1', 'data2', 'data3']]
    },
    axis: {rotated: true}
});

// 畫出基本的圓餅圖
var pieChart = c3.generate({
    bindto: '#pie-chart',
    data: {
      columns: [['data1', 30, 200, 100, 400, 150, 250],
                ['data2', 50, 20, 10, 40, 15, 25],
                ['data3', 130, 150, 200, 300, 200, 100]], 
      type: 'pie'
    }
});

https://ithelp.ithome.com.tw/upload/images/20191008/20120178VO0XBw9lo8.png
  經過前幾天的折磨?我們已經可以很快的畫出兩張圖表了。如圖二

建構圖表相依性:使用 C3 API

  接著就是要來讓這兩張圖表知道,他們之間是有關係的。當我們的滑鼠游標移到圓餅圖的'data1'標籤時,在柱狀圖的'data1'也要跟著被標示出來。
  怎麼做到呢?
  首先,這兩張圖表之間的數據要「真的」有關聯,我指的是代表數據當中每一筆資料的名稱要一樣。在這個例子中,圓餅圖的 3 組資料分別叫做'data1''data2''data3'、那麼柱狀圖的 3 組資料我們也會這麼命名。

  接著就來用 C3 提共給我們的應用程式編程介面(API),讓這兩張圖「知道」他們是相連的。在 C3 裡面,一張圖表的組成包括有datalegend,如剛才圖二紅框處標示的。當然還有其他的,不過目前我們要介紹的是這兩個。

  什麼設定都不改動的情況下,滑鼠指標移到datalegend處,相對應的資料會被加強顯示。此外,點擊legend上特定的資料名稱時,data處的該筆資料會被隱藏/顯示。
  所謂讓兩張圖知道他們是相連的,就是要做出這種效果。當我們把滑鼠指標移到圓餅圖上的特定資料時,柱狀圖上相對應的資料也會跟著被加強顯示。
  這就跟我們之前學過的 HTML 5 事件處理器有點像,C3 也提供了類似的參數供我們使用。等等會用到的有onmouseover當滑鼠指標移入、onmouseout當滑鼠指標移出、onclick當滑鼠點擊。不囉嗦,直接來看個程式碼:

var barChart = c3.generate({
    bindto: '#barChart',
    data: {
      columns: [以下略], 
      type:'bar', 
      groups:[['data1', 'data2', 'data3']]
    },
    axis: {rotated: true},
    legend: {hide: true}  // 我們把柱狀圖的 legend 藏起來
});

var pieChart = c3.generate({
    bindto: '#pieChart',
    data: {
      columns: [以下略], 
      type: 'pie', 
      onmouseover: function (e){barChart.focus(e.id); pieChart.focus(e.id)},  // 新增 onmouseover
      onmouseout: function (e){barChart.focus(); pieChart.focus()}  // 新增 onmouseout
    },
    legend:{
        item:{
            onmouseover: function (e){barChart.focus(e); pieChart.focus(e)},  // 新增 onmouseover
            onmouseout: function (e){barChart.focus(); pieChart.focus()},  // 新增 onmouseout
            onclick: function (e){barChart.toggle(e); pieChart.toggle(e)}  // 新增 onclick
    }
    }
});

  我們把 JavaScript 當中請 C3 來畫圖的程式碼稍做修改。相同的部份我就不多做解釋了,只來看看那些我們增加的段落。

  • 第九行: legend: {hide: true}
      加入一個legend的鑰匙來控制我們的圖例,並在其中放入一個{hide: true}物件代表我們想要將這個圖例藏起來。

  • 第十六行: onmouseover: function (e){barChart.focus(e.id); pieChart.focus(e.id)},
      在data當中放入一個onmouseover鑰匙,有點像是加入了 HTML 5 事件處理器,處理的事件是當滑鼠指標移動到data上時,就執行後方的程式碼。看看後方的程式碼寫了些什麼:

function (e) { barChart.focus(e.id); pieChart.focus(e.id) }

  我們利用barChart來呼叫一開始宣告過代表柱狀圖的變數,focus()則是 C3 提供的函數,用來加強顯示指定的資料,用法如:

chart.focus('data1');  // 加強顯示`data1`

chart.focus(['data1', 'data2']);  // 加強顯示`data1`以及`data2`

chart.focus();  // 加強顯示圖表中所有資料

  因此整行程式碼的意思是,當滑鼠移到data上時,我們藉由e.id來呼叫該項資料,並加強顯示該項資料。另外注意一件事,我們不僅加強顯示了pieChart的資料,同時也加強顯示了barChart的資料。這樣一來,當滑鼠移至pieChartdata1時,不僅pieChartdata1會被加強顯示,barChartdata1也會,看起來就像兩份圖表的資料連接在一起了一樣!

  • 第十七行: onmouseout: function (e){barChart.focus(); pieChart.focus()}
      同理,當滑鼠指標移開data時,加強顯示所有資料。

  • 第二十一行: onmouseover: function (e){barChart.focus(e); pieChart.focus(e)},
      我們先是新增了一個legend鑰匙,放入物件,又再該物件當中新增item鑰匙,最後才放入我們要的onmouseover參數。

  • 第二十三行: onclick: function (e){barChart.toggle(e); pieChart.toggle(e)}
      加入一個onclick參數,代表我們還想要處理滑鼠點擊事件。在滑鼠點擊圖例的時候,我們再次同時呼叫了barChartpieChart,並利用 C3 提供的函數toggle(),來讓資料再data中顯示/隱藏。

  這樣就簡簡單單的做出兩張連在一起的圖表了!有沒有突然覺得我們跟圖一的距離也沒想像中的遠呢?把我們學過的技巧融會貫通,就可以試著朝我們的圖一邁進了。

https://ithelp.ithome.com.tw/upload/images/20191008/201201781ZCwA8vVgx.png
圖三、試著運用我們所學會的各種技巧,一步一步向圖一靠近吧

  這個系列的主題就到這裡結束了。最後在這邊放上一些我覺得挺有幫助的資源供大家參考:

  1. Introducing Python 讀書筆記
  2. line-bot-sdk-python 官方文件
  3. twtrubiks 的 LINE BOT 教學
  4. PostgreSQL 中文手冊
  5. PostgreSQL 教學
  6. psycopg2 教學
  7. flask 官方文件
  8. flask 教學
  9. jinja2 官方文件
  10. Flask-Login 教學
  11. Eloquent JavaScript 下載
  12. MDN 開放資源 資料庫
  13. W3School 資料庫

  最後要說的是,英文真的很重要,鼓勵大家認真的學一學。上面那麼多資源,一半以上都是英文的文件。如果可以看懂英文,那麼在這個領域的學習一定可以輕鬆很多!謝謝大家這 30 天來的支持與關照,若有疑問,歡迎大家一樣在文章下面留言,我會盡可能的答覆的!祝大家在學習程式的路上都能滿意開心!

註:對於此系列文有興趣的讀者,歡迎參考由此系列文擴編成書的 LINE Bot by Python,以及最新的系列文《賴田捕手:追加篇》
第 31 天 初始化 LINE BOT on Heroku
第 32 天 快速回覆 QuickReply 介紹
第 33 天 妥善運用 Heroku APP 暫存空間
第 34 天 妥善運用 LINE Notify 免費推播
第 35 天 製造 Deploy to Heroku 按鈕


上一篇
第 29 天:DataVis:C3 Stanford
系列文
從LINE BOT到資料視覺化:賴田捕手30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
阿展展展
iT邦好手 1 級 ‧ 2020-02-27 08:22:48

恭喜完賽 恭喜獲得優選!

我要留言

立即登入留言